#pragma once

#include "../../base/obj_pointer.h"
#include "../../vmath/vec2i.h"
#include "../../vmath/box2.h"
#include "gl.h"

OPEN_JLIB_NS


struct TexParam {
  GLint minFilter {GL_LINEAR};
  GLint magFilter {GL_LINEAR};
  GLint wrapS {GL_CLAMP_TO_EDGE};
  GLint wrapT {GL_CLAMP_TO_EDGE};
};


struct Texture : public Obj {

  ~Texture () override;

  bool init (GLsizei w, GLsizei h, GLenum fmt, GLenum type, const GLvoid* data = nullptr, const TexParam& param = TexParam());
  bool reload (GLsizei w, GLsizei h, GLenum fmt, GLenum type, const GLvoid* data);
  void setParam (const TexParam& param);
  void bind (GLuint bindingPoint);
  void clear ();

  inline bool valid () const noexcept { return _id != 0; }
  inline GLuint id () const noexcept { return _id; }
  inline GLsizei width () const noexcept { return _w; }
  inline GLsizei height () const noexcept { return _h; }
  inline Vec2i size () const noexcept { return {_w, _h}; }

protected:
  GLuint _id {0};
  GLsizei _w;
  GLsizei _h;
};


struct TexFrame : public Obj {

  bool init (Texture* tex);
  bool init (Texture* tex, const Box2& rect);

  inline bool valid () const noexcept { return _tex && _tex->valid(); }

  inline Texture* getTexture () noexcept { return _tex.ptr(); }
  inline void setTexture (Texture* tex) { _tex = tex; }

  inline Box2 getRect () const noexcept { return _rect; }
  inline void setRect (Box2 rect) noexcept { _rect = rect; }

protected:
  Box2 _rect;
  Ptr<Texture> _tex;
};


CLOSE_JLIB_NS


